package com.fenquen.dfs.storage.multicast;

import com.fenquen.dfs.storage.config.DFSStorageConfig;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.nio.NioDatagramChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.InetSocketAddress;

@Configuration
public class NettyConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(NettyConfig.class);

    @Autowired
    private DFSStorageConfig dfsStorageConfig;

    @Bean
    public Channel channel() {
        dfsStorageConfig.multicastAddress =
                new InetSocketAddress(dfsStorageConfig.multicastHost, dfsStorageConfig.multicastPort);

        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

        //  NetworkInterface ni = NetworkInterface.getByName("en1");

        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup)
                .channelFactory(() -> new NioDatagramChannel(InternetProtocolFamily.IPv4))
                .localAddress(dfsStorageConfig.udpHost, dfsStorageConfig.udpPort)
                // .option(ChannelOption.IP_MULTICAST_IF, ni)
                .option(ChannelOption.SO_REUSEADDR, true).handler(new MulticastClientHandler());

        ChannelFuture channelFuture = null;
        try {
            channelFuture = bootstrap.bind().sync();
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage(), e);
        }

        if (channelFuture != null && channelFuture.isSuccess()) {
            return channelFuture.channel();
        }

        if (channelFuture != null) {
            LOGGER.error("", channelFuture.cause());
        }

        eventLoopGroup.shutdownGracefully();

        System.exit(0);

        // channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("client message".getBytes(StandardCharsets.UTF_8)), groupAddress));


        //  channel.closeFuture().await();

        return null;
    }
}
